#ifndef NTABLEVIEW_H
#define NTABLEVIEW_H

#include <QStandardItemModel>
#include <QTableView>
#include <QWidget>
#include <QHeaderView>
#include "NCore/GY_NPage.h"
#include "GY_ControlLibrary_global.h"
#include "GY_WidgetReflect.h"
#include "NCore/GY_NStyle.h"
#include <QDebug>

class GY_CONTROLLIBRARY_EXPORT GY_NTableView : public QTableView , public GY_NPage , public GY_NStyle
{
    Q_OBJECT
signals:
    void clickedCustomWidged(const QVariant &id,const qint32 columenIndex,const QVariant &data , const QModelIndex &index = QModelIndex());

public:
    explicit GY_NTableView(QWidget *parent = nullptr);
    /**
     * @brief setColumnCount 设置列数量
     * @param value
     */
    void setColumnCount(int value);
    /**
     * @brief addColumnName 添加列名称并添加列
     * @param name
     */
    void addColumnName(const QString &name);
    template<typename T>
    void addColumnNameAndRegisterControl(const QString &name);
    /**
     * @brief setHasCheckBox //设置是否将第一列设置成复选框,如果设置成 true, 则在设置列数时，需要加1,插入数据时，第一个数据也需要用 "" 空字符串占位
     * @param value
     */
    void setHasCheckBox(bool value);
    /**
     * @brief setRowCheckState 设置某行的选中状状态
     * @param row
     * @param isChecked
     */
    void setRowCheckState(int row, bool isChecked);
    /**
     * @brief isCheckedAtRow 获取某行是否选中
     * @param row
     * @return
     */
    bool isCheckedAtRow(int row);
    /**
     * @brief getCheckedDatas 获取选中的数据
     * @param list
     */
    void getCheckedDatas(QList<QList<QVariant>> &list);
    /**
     * @brief getCheckedIds 获取选中的所有id
     * @param list
     */
    void getCheckedIds(QList<int> &list);
    void getCheckedIds(QList<QVariant> &list);

    /**
     * @brief getDataById 通过id获取数据
     * @param id
     * @return
     */
    QList<QVariant> getDataById(const QVariant &id);
    void updateDataById(const QVariant &id, const QList<QVariant> &list);
    /**
     * @brief deleteCheckedRow 删除选中行
     */
    void deleteCheckedRow();
    /**
     * @brief deleteRowByRow删除目标行
     * @param row
     */
    void deleteRowByRow(int row);
    /**
     * @brief deleteRowById 删除目标ID
     * @param id
     */
    void deleteRowById(const QVariant &id);
    /**
     * @brief addRowData 添加行数据
     * @param list
     * @param id
     * @return
     */
    int addRowData(const QList<QVariant> &list, const QVariant &id = -1);
    /**
     * @brief getModelIndexById 获取某id所在行的 QModelIndex
     * @param id
     * @return
     */
    QModelIndex getModelIndexById(const QVariant &id);
    /**
     * @brief removeAllData 删除所有
     */
    void removeAllData();
    //!注册自定义控件
    template<typename T>
    bool registerControl(qint32 columnIndex);
    /**
     * @brief getRowCount 获取行数
     * @return 返回行数
     */
    qint32 getRowCount();
    void setLineHeight(int LineHeight);

    QStandardItemModel *getViewModel() const;
    /**
     * @brief getDataByModleIndex 获取指定modeindex数据
     * @param index
     * @return
     */
    QList<QVariant> getDataByModeIndex(const QModelIndex &index);
    /**
     * @brief getIdByModeIndex 获取指定ModeIndex的数据ID
     * @param index
     * @return
     */
    QVariant getIdByModeIndex(const QModelIndex &index);
private:
    //!注册控件信息
    QMap<qint32,QString> m_RegisterInfo;
    //!表格model
    QStandardItemModel* m_pViewModel;
    //!行高
    int m_LineHeight = 50;
    //!列数
    int m_ColumnNumber = 1;
    //!当前列索引
    int m_CoverColumnIndex = 0;
    //!支持显示的数据总数
    int m_dataCount=0;
    //!是否在将第一列设置成复选框
    bool m_hasCheckBox =  false;
    //!数据角色
    const static int m_dataRole;
    //!Id角色
    const static int m_IdRole;
    //!存放注册类型构造函数
    QHash<QString,WidgetReflect::Constructor> m_RegisterHash;
};
/**
 *registerControl 注册控件
 */
template<typename T>
bool GY_NTableView::registerControl(qint32 columnIndex)
{
    if(columnIndex>=m_ColumnNumber)
    {
        return false;
    }
    WidgetReflect::Constructor pFun= WidgetReflect::registerClass<T>();
    if(m_RegisterInfo.contains(columnIndex))
    {
        m_RegisterInfo.remove(columnIndex);
    }
    QString className = QString(T::staticMetaObject.className());
    m_RegisterInfo.insert(columnIndex, className);
    m_RegisterHash.insert(className,pFun);
    return true;
}
template<typename T>
void GY_NTableView::addColumnNameAndRegisterControl(const QString &name)
{
    int targetColumn = m_CoverColumnIndex + (m_hasCheckBox ? 1 : 0);
    m_pViewModel->setHeaderData(targetColumn,Qt::Horizontal,name);
    registerControl<T>(targetColumn);
    m_CoverColumnIndex++;
}

#endif // NTABLEVIEW_H
